package com.cet.test.mt03;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Stream;

/**
 * @program: cet-practice
 * @description: 文件合并
 * @author: 陈恩涛
 * @create: 2023-04-24 19:34
 **/
public class FilesMerge {

    public static void main(String[] args) throws IOException {

        ExecutorService exec = Executors.newCachedThreadPool();

        List<String> filePaths = new ArrayList<>();

        List<FileInputStream> fileInputStreams = new CopyOnWriteArrayList<>();

        try (Stream<Path> paths = Files.walk(Paths.get("D:\\test")); FileInputStream ai = new FileInputStream("D:\\a.txt"); FileInputStream bi = new FileInputStream("D:\\b.txt"); FileInputStream ci = new FileInputStream("D:\\c.txt"); FileOutputStream fos = new FileOutputStream("D:\\merge.txt")) {
            paths
                .filter(Files::isRegularFile)
                .forEach(path -> filePaths.add(path.toString()));

            // 一次性将所有文件加载到缓存中，cpu压力会不会太大
            CountDownLatch countDownLatch = new CountDownLatch(filePaths.size());

            //分批读取，一次读5个文件，将文件内容写到merge.txt中
            CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> {
                // 读取5个文件后，向merge.txt中写入
                int len = 0;
                byte[] bytes = new byte[1024 * 1024];
                try {
                    for (FileInputStream fileInputStream : fileInputStreams) {
                        while ((len = fileInputStream.read(bytes)) != -1) {
                            fos.write(bytes, 0, len);
                            fos.flush();
                        }
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });

            // last group can not attain to 5, so just handle them sequentially
            if (filePaths.size() % 5 != 0) {

            }



        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
